Tic-Tac-Toe
Volume Number: 1
Issue Number: 12
Column Tag: Lisp Listener
Windows and Tic-Tac-Toe!
By Andy Cohen, Human Factors Engineer, MacTutor Contributing Editor
This month the Lisp Listener will feature a program written by Dean Ritz of
ExperTelligence. The program is a Tic-Tac-Toe game which uses all of the functions
described in previous issues. However, before discussing the game I'd like to present a
subject long overdue.
Menus In ExperLisp
Creating a menu on the menu bar is actually a pretty straight forward, though
nonintuitve, operation. In creating a menu one must use one of the special "hooks" in
ExperLisp. There are also hooks for printing. Those will eventually be covered in
future installments. The first step in creating a menu must be the identification of
what the menu items will do. Menu items can call functions or perform assignment. If
the items call defined functions, these functions should already be defined and the
function names known. One then defines a function which returns a menu and a menu
item on the condition that a certain menu and item position is selected. One easy way to
do this uses a conditional which has not yet been discussed.
SELECTQ acts like COND since it has a clause and returns something based on the
value of the clause. The first item following the term SELECTQ is the key-form . Each
of the test items which follow are evaluated and the one which is the equivalent of the
key-form causes the return of it's corresponding value or list. For example;
(defun what (x)
(selectq x
(1 'one)
(2 'two)
(t 'all)))
(what 1)
one
(what 3)
all
In the above, the selectq evaluates the passed value (x) for equality with the first
atoms of each of the three following lists. If the atom is equal to the passed value, the
atom following the first is returned. As in COND the "t" forces the return of the atom
"all". In assigning menu item positions one may have a SELECTQ within a SELECTQ. The
first level SELECTQ finds the menu, the second finds the menu item. For example:
(defun menuselect (themenu theitem)
(selectq themenu
(10 (selectq theitem
(1 (function1B))
(2 (function2B))
(3 (function3B))))
(11 (selectq theitem
(1 (function1A))
(2 (function2A))
(3 (function3A))))))
The first SELECTQ locates which group of items belong to the menu number
assigned to "themenu". The second SELECTQ locates the item belonging to the item
number assigned to "theitem". After one generates the above defined function one must
assign the values returned by the function to the special menu-hook;
(setq ªmenuhook menusel)
One then assigns a label to the "NEWMENU" function (It is a built in function)
and it's elements. This must be done with the ID number that one wants to assign to the
menu as well as the menu title. For example:
(setq mymenu (newmenu 10 "menu B"))
Using this label one then assigns the item labels to the menu as follows:
(appendmenu mymenu "function1B")
(appendmenu mymenu "function2B")
(appendmenu mymenu "function3B")
or one may do it all in one list as follows:
(appendmenu mymenu " function1B; function2B;
function3B")
One then inserts the menu with:
(insertmenu mymenu 0)
Then draws it with:
(drawmenubar)
The entire sample with dummy functions follows:
(defun function1A ()
(print "function 1A"))
(defun function2A ()
(print "function 2A"))
(defun function3A ()
(print "function 3A"))
(defun function1B ()
(print "function 1B"))
(defun function2B ()
(print "function 2B"))
(defun function3B ()
(print "function 3B"))
(defun menuselect (themenu theitem)
(selectq themenu
(10 (selectq theitem
(1 (function1B))
(2 (function2B))
(3 (function3B))))
(11 (selectq theitem
(1 (function1A))
(2 (function2A))
(3 (function3A))))))
(setq ªmenuhook menuselect)
(setq mymenu (newmenu 10 "menu B")
grmenu (newmenu 11 "menu A"))
(appendmenu grmenu
function1A;function2A;function3A)
(appendmenu mymenu
"function1B;function2B;function3B")
(insertmenu grmenu 0) ;0=the beforeID #